#ifndef _imageDelegate_h_
#define _imageDelegate_h_

// imageDelegate.h
//
// Image delegation object to allow optimized implementations of 
// image processing functions to be used dynamically.


// Disable the warning regarding long symbol names caused by templates
#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif


#include "image/imageTypes.h"
#include "image/imageStorageTmpl.h"

#include <string>
#include <map>

namespace simple{

    // Generic definition of a function that takes 2 args and returns 1
    template<class S1, class S2, class D1>
    class SSD
    {
    public:
        virtual ~SSD () {}

        virtual bool operator() (const ImageStorage<S1>& s1, const ImageStorage<S2>& s2, ImageStorage<D1>& d1) const = 0;
    };


    //
    // ImageDelegate
    //
    // typedef ImageStorage<T> (*functionSD)  (const ImageStorage<T>&);
    // typedef ImageStorage<T> (*functionSSD) (const ImageStorage<T>&, const ImageStorage<T>&);


    // 

    class ImageDelegate
    {
    public:
        typedef void (*Function) ();

        typedef ImageStorage<Pel8>  (*FunctionS8D8)         (const ImageStorage<Pel8>&);
        typedef ImageStorage<Pel32s>(*FunctionS32D32)       (const ImageStorage<Pel32s>&);
        typedef ImageStorage<RGB>   (*FunctionSrgbDrgb)     (const ImageStorage<RGB>&);

        typedef ImageStorage<Pel8>  (*FunctionS8S8D8)     (const ImageStorage<Pel8>&,
                                     const ImageStorage<Pel8>&);
        typedef ImageStorage<Pel32s>(*FunctionS32S32D32)    (const ImageStorage<Pel32s>&,
                                     const ImageStorage<Pel32s>&);
        typedef ImageStorage<RGB>   (*FunctionSrgbSrgbDrgb) (const ImageStorage<RGB>&,
                                     const ImageStorage<RGB>&);

        typedef std::map<std::string, Function> Typemap;
        typedef std::map<std::string, Typemap>  Functionmap;

        static ImageDelegate& gOnly();


        void addDelegate (std::string name, FunctionS8D8 function);

    protected:
        ImageDelegate ();

        static ImageDelegate* _sOnly;

        Typemap         _typemap;
        Functionmap _functionmap;
    };

    /*
    class ImageFunction
    {
    };

    class ImageFunctionS8D8 : public ImageFunction
    {
    public:
        typedef ImageStorage<Pel8> (*Function) (const ImageStorage<Pel8>&);

        static ImageFunctionS8D8& gOnly();


        void add (std::string name, ImageDelegate::FunctionS8D8 function);
        ImageDelegate::FunctionS8D8 fetch (std::string name);

    private:
        ImageFunctionS8D8 ();

        static ImageFunctionS8D8* _sOnly;

        Typemap     _typemap;
        Functionmap _functionmap;
    };
    */
}
#endif // _imageDelegate_h_
